#region Usings

using System;
using NUnit.Framework;
using Karma.Framework.Core.Domain.Tools.Import.Layout;
using Karma.Framework.Core.Test.Domain.Tools.Importador.Entidades;

#endregion

namespace Karma.Framework.Core.Test.Domain.Tools.Importador
{
    [TestFixture]
    public class LayoutFactoryFixture
    {
        [Test]
        public void GeneraLayoutEntidadAnidadaTest()
        {
            var factory = new DefaultLayoutFactory();
            var layout = factory.Create<EntidadAnidada>(new LayoutFactoryConfig {GenerateAggregates = true},
                                                        new Type[] {});

            Assert.IsNotNull(layout);
            Assert.IsNotNull(layout.Properties);
            Assert.AreEqual(4, layout.Properties.Count);

            Assert.AreEqual("Entidad", layout.Properties[3].Name);

            var keyref = (ReferenceField) layout.Properties[3];
            Assert.AreEqual(typeof (EntidadAnidada), keyref.FieldType);
            Assert.AreEqual(true, keyref.Nullable);
            Assert.AreEqual(null, keyref.KeyRef);
            Assert.AreEqual(typeof (int), keyref.KeyRefType);

            Assert.IsNotNull(layout.Aggregates);
            Assert.AreEqual(1, layout.Aggregates.Count);
            Assert.AreEqual(typeof (EntidadAnidada), layout.Aggregates[0].Entity);
            Assert.IsNotNull(layout.Aggregates[0].Properties);
            Assert.AreEqual(4, layout.Aggregates[0].Properties.Count);
        }

        [Test]
        public void GeneraLayoutEntidadConAgregadosTest()
        {
            var factory = new DefaultLayoutFactory();
            var layout =
                factory.Create<EntidadConAsociadosYAgregados>(new LayoutFactoryConfig {GenerateAggregates = true},
                                                              new Type[] {});

            Assert.IsNotNull(layout);
            Assert.IsNotNull(layout.Properties);
            Assert.AreEqual(4, layout.Properties.Count);

            Assert.IsNotNull(layout.Aggregates);
            Assert.AreEqual(1, layout.Aggregates.Count);
            Assert.AreEqual(typeof (OtraEntidadSimple), layout.Aggregates[0].Entity);
            Assert.IsNotNull(layout.Aggregates[0].Properties);
            Assert.AreEqual(4, layout.Aggregates[0].Properties.Count);
        }

        [Test]
        public void GeneraLayoutEntidadConAsociadosDefaultTest()
        {
            var factory = new DefaultLayoutFactory();
            var layout = factory.Create<EntidadConAsociados>(new LayoutFactoryConfig(), new Type[] {});

            Assert.IsNotNull(layout);
            Assert.IsNotNull(layout.Properties);
            Assert.AreEqual(4, layout.Properties.Count);

            Assert.AreEqual("Entidad", layout.Properties[3].Name);
            Assert.AreEqual(typeof (EntidadSimple), layout.Properties[3].FieldType);
            var keyRef = (ReferenceField) layout.Properties[3];
            Assert.AreEqual(typeof (int), keyRef.KeyRefType);
            Assert.AreEqual(false, layout.Properties[3].Nullable);
            Assert.AreEqual(null, keyRef.KeyRef);
        }

        [Test]
        public void GeneraLayoutEntidadConAsociadosIdRefTest()
        {
            var factory = new DefaultLayoutFactory();
            var layout = factory.Create<EntidadConAsociadosConIdRef>(new LayoutFactoryConfig(), new Type[] {});

            Assert.IsNotNull(layout);
            Assert.IsNotNull(layout.Properties);
            Assert.AreEqual(4, layout.Properties.Count);

            Assert.AreEqual("Entidad", layout.Properties[3].Name);
            var keyref = (ReferenceField) layout.Properties[3];
            Assert.AreEqual(typeof (EntidadSimple), keyref.FieldType);
            Assert.AreEqual(false, keyref.Nullable);
            Assert.IsNotNull(keyref.KeyRef);
            Assert.AreEqual("Cadena", keyref.KeyRef);
            Assert.AreEqual(typeof (string), keyref.KeyRefType);
        }

        [Test]
        public void GeneraLayoutEntidadSimpleConConstraintTest()
        {
            var factory = new DefaultLayoutFactory();
            var layout = factory.Create<EntidadSimpleConConstraint>(new LayoutFactoryConfig(), new Type[] {});

            Assert.IsNotNull(layout);
            Assert.IsNotNull(layout.Properties);
            Assert.AreEqual(3, layout.Properties.Count);

            Assert.AreEqual("Cadena", layout.Properties[0].Name);
            Assert.AreEqual(typeof (string), layout.Properties[0].FieldType);
            Assert.AreEqual(false, layout.Properties[0].Nullable);
            Assert.AreEqual("CadenaKey", layout.Properties[0].UniqueKey);
        }

        [Test]
        public void GeneraLayoutEntidadSimpleConFormulaTest()
        {
            var factory = new DefaultLayoutFactory();
            var layout = factory.Create<EntidadSimpleConFormula>(new LayoutFactoryConfig(), new Type[] {});

            Assert.IsNotNull(layout);
            Assert.IsNotNull(layout.Properties);
            Assert.AreEqual(5, layout.Properties.Count);

            Assert.AreEqual("Cadena", layout.Properties[0].Name);
            Assert.AreEqual(typeof (string), layout.Properties[0].FieldType);
            Assert.AreEqual(false, layout.Properties[0].Nullable);
            Assert.IsNotNull(((PropertyField) layout.Properties[0]).Formula);
            Assert.AreEqual("Entero+Entero2+Entero3", ((PropertyField) layout.Properties[0]).Formula);
        }

        [Test]
        public void GeneraLayoutEntidadSimpleConHerenciaTest()
        {
            var factory = new DefaultLayoutFactory();
            var layout = factory.Create<EntidadSimpleConHerencia>(new LayoutFactoryConfig(), new Type[] {});

            Assert.IsNotNull(layout);
            Assert.IsNotNull(layout.Properties);
            Assert.AreEqual(4, layout.Properties.Count);

            Assert.AreEqual("OtroEntero", layout.Properties[0].Name);
            Assert.AreEqual(typeof (int), layout.Properties[0].FieldType);
            Assert.AreEqual(true, layout.Properties[0].Nullable);

            Assert.AreEqual("Cadena", layout.Properties[1].Name);
            Assert.AreEqual(typeof (string), layout.Properties[1].FieldType);
            Assert.AreEqual(false, layout.Properties[1].Nullable);

            Assert.AreEqual("Entero", layout.Properties[2].Name);
            Assert.AreEqual(typeof (int), layout.Properties[2].FieldType);
            Assert.AreEqual(true, layout.Properties[2].Nullable);

            Assert.AreEqual("Fecha", layout.Properties[3].Name);
            Assert.AreEqual(typeof (DateTime), layout.Properties[3].FieldType);
            Assert.AreEqual(true, layout.Properties[3].Nullable);
        }

        [Test]
        public void GeneraLayoutEntidadSimpleConHerenciaTiposExcluidos2Test()
        {
            var factory = new DefaultLayoutFactory();
            var layout = factory.Create<OtraEntidadSimpleConHerencia>(new LayoutFactoryConfig(),
                                                                      new[] {typeof (EntidadSimple)});

            Assert.IsNotNull(layout);
            Assert.IsNotNull(layout.Properties);
            Assert.AreEqual(4, layout.Properties.Count);

            Assert.AreEqual("OtraCadena", layout.Properties[0].Name);
            Assert.AreEqual(typeof (string), layout.Properties[0].FieldType);

            Assert.AreEqual("OtroEntero2", layout.Properties[1].Name);
            Assert.AreEqual(typeof (int), layout.Properties[1].FieldType);

            Assert.AreEqual("OTraFecha", layout.Properties[2].Name);
            Assert.AreEqual(typeof (DateTime), layout.Properties[2].FieldType);

            Assert.AreEqual("OtroEntero", layout.Properties[3].Name);
            Assert.AreEqual(typeof (int), layout.Properties[3].FieldType);
        }

        [Test]
        public void GeneraLayoutEntidadSimpleConHerenciaTiposExcluidosTest()
        {
            var factory = new DefaultLayoutFactory();
            var layout = factory.Create<OtraEntidadSimpleConHerencia>(new LayoutFactoryConfig(),
                                                                      new[] {typeof (EntidadSimpleConHerencia)});

            Assert.IsNotNull(layout);
            Assert.IsNotNull(layout.Properties);
            Assert.AreEqual(6, layout.Properties.Count);

            Assert.AreEqual("OtraCadena", layout.Properties[0].Name);
            Assert.AreEqual(typeof (string), layout.Properties[0].FieldType);

            Assert.AreEqual("OtroEntero2", layout.Properties[1].Name);
            Assert.AreEqual(typeof (int), layout.Properties[1].FieldType);

            Assert.AreEqual("OTraFecha", layout.Properties[2].Name);
            Assert.AreEqual(typeof (DateTime), layout.Properties[2].FieldType);

            Assert.AreEqual("Cadena", layout.Properties[3].Name);
            Assert.AreEqual(typeof (string), layout.Properties[3].FieldType);

            Assert.AreEqual("Entero", layout.Properties[4].Name);
            Assert.AreEqual(typeof (int), layout.Properties[4].FieldType);

            Assert.AreEqual("Fecha", layout.Properties[5].Name);
            Assert.AreEqual(typeof (DateTime), layout.Properties[5].FieldType);
        }

        [Test]
        public void GeneraLayoutEntidadSimpleTest()
        {
            var factory = new DefaultLayoutFactory();
            var layout = factory.Create<EntidadSimple>(new LayoutFactoryConfig(), new Type[] {});

            Assert.IsNotNull(layout);
            Assert.IsNotNull(layout.Properties);
            Assert.AreEqual(3, layout.Properties.Count);

            Assert.AreEqual("Cadena", layout.Properties[0].Name);
            Assert.AreEqual(typeof (string), layout.Properties[0].FieldType);
            Assert.AreEqual(false, layout.Properties[0].Nullable);

            Assert.AreEqual("Entero", layout.Properties[1].Name);
            Assert.AreEqual(typeof (int), layout.Properties[1].FieldType);
            Assert.AreEqual(true, layout.Properties[1].Nullable);

            Assert.AreEqual("Fecha", layout.Properties[2].Name);
            Assert.AreEqual(typeof (DateTime), layout.Properties[2].FieldType);
            Assert.AreEqual(true, layout.Properties[2].Nullable);
        }
    }
}